package ae.pcfc.etks.online.web.controller.user.general.home;

/* $Id: RegisterController 
 * Copyright (C) 2011, Trakhees
 *  
 *  History
 *
 * Date  			Author 					Remarks
 * -------------------------------------------------------------
 * April 10, 2011 	Mohtisham.Salahria      Created
 *
 */

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.util.WebUtils;

import ae.pcfc.etks.online.common.delegate.AppMetaDataDelegate;
import ae.pcfc.etks.online.common.delegate.ServiceDelegate;
import ae.pcfc.etks.online.common.delegate.UserDelegate;
import ae.pcfc.etks.online.common.exception.DuplicateClientNameException;
import ae.pcfc.etks.online.common.util.CommonUtils;
import ae.pcfc.etks.online.common.vo.AppMetaDataDetailVO;
import ae.pcfc.etks.online.common.vo.AppMetaDataVO;
import ae.pcfc.etks.online.common.vo.ClientCompanyVO;
import ae.pcfc.etks.online.common.vo.PagingVO;
import ae.pcfc.etks.online.common.vo.ServiceVO;
import ae.pcfc.etks.online.common.vo.UserRequestVO;
import ae.pcfc.etks.online.common.vo.UserVO;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.model.ClientLogin;
import ae.pcfc.etks.online.web.model.JQGridJSONModel;
import ae.pcfc.etks.online.web.model.Service;
import ae.pcfc.etks.online.web.util.SecurityUtils;

/**
 * Controller that handles all {@link HomeController}-related requests, i.e.:
 * all requests for /user/general/home/*
 * 
 * @author Mohtisham.Salahria
 */
@Controller
@RequestMapping(ViewPath.USER_GENERAL_HOME)
public class HomeController extends BaseController{

	private UserDelegate userDelegate;

	@Resource(name = "userDelegate")
	public void setUserDelegate(UserDelegate userDelegate) {
		this.userDelegate = userDelegate;
	}

	private ServiceDelegate serviceDelegate;

	@Resource(name = "serviceDelegate")
	public void setServiceDelegate(ServiceDelegate serviceDelegate) {
		this.serviceDelegate = serviceDelegate;
	}

/*	private UserAnnouncementDelegate userAnnouncementDelegate;

	@Resource(name = "userAnnouncementDelegate")
	public void setUserAnnouncementDelegate(UserAnnouncementDelegate userAnnouncementDelegate) {
		this.userAnnouncementDelegate = userAnnouncementDelegate;
	}
*/
	private AppMetaDataDelegate appMetaDataDelegate;

	@Resource(name = "appMetaDataDelegate")
	public void setAppMetaDataDelegate(AppMetaDataDelegate appMetaDataDelegate) {
		this.appMetaDataDelegate = appMetaDataDelegate;
	}


	// @ModelAttribute(Constants.USER_SERVICE_LIST_REQUEST_MODEL_KEY)
	@RequestMapping(value = "/userServiceList", method = RequestMethod.GET)
	@ResponseBody
	public List<Service> getUserServiceList(HttpServletRequest request) {

		List<Service> serviceModels = new ArrayList<Service>();

		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String strUserName = null;

		if (principal instanceof UserDetails) {
			strUserName = ((UserDetails) principal).getUsername();
		} else {
			strUserName = principal.toString();
		}

		List<ServiceVO> serviceVOs = this.serviceDelegate.findServiceListByUserName(strUserName);

		if (serviceVOs != null && serviceVOs.size() > 0) {
			Service service;
			for (ServiceVO serviceVO : serviceVOs) {
				service = new Service();
				getMapper().map(serviceVO, service);
				serviceModels.add(service);
			}
			// map.addAttribute("serviceRegisterRefrenceData", serviceModels);
		}

		return serviceModels;
	}

	@RequestMapping(value = "/userAnnouncement", method = RequestMethod.GET)
	@ResponseBody
	public List<UserRequestVO> getUserAnnouncement(HttpServletRequest request) {

		List<UserRequestVO> userRequestVOs;
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String strUserName = null;

		if (principal instanceof UserDetails) {
			strUserName = ((UserDetails) principal).getUsername();
		} else {
			strUserName = principal.toString();
		}

		if (strUserName != null) {

			UserVO userVO = this.userDelegate.findUserByUserName(strUserName);

			if (userVO != null && userVO.getlUserId() != null) {
				userRequestVOs = new ArrayList<UserRequestVO>();

				List<AppMetaDataDetailVO> appMetaDataVOs = this.appMetaDataDelegate.loadCompletedAppMetaDataByUserId(userVO.getlUserId());
//				AppMetaDataDetailVO appMetaDataDetailVO = new AppMetaDataDetailVO();
//				appMetaDataDetailVO.setlUserId(userVO.getlUserId());
//				appMetaDataDetailVO.setStrStatusDescEn(this.messageSource.getMessage("msg.workflow.status.in.progress", null, Locale.ENGLISH));
//				List<AppMetaDataDetailVO> appMetaDataVOs = this.appMetaDataDelegate.loadCompletedAppMetaDataByUserId(appMetaDataDetailVO);
				UserRequestVO userRequestVO;

				if(appMetaDataVOs != null && appMetaDataVOs.size() > 0)
				{
					for (AppMetaDataVO appMetaDataVO : appMetaDataVOs) {
	
						userRequestVO = new UserRequestVO();
						getMapper().map(appMetaDataVO, userRequestVO);
						userRequestVOs.add(userRequestVO);
					}
					if (userRequestVOs.size() > 0) {
						return userRequestVOs;
					}
				}
			}
		}

		return null;

	}

	@RequestMapping(value = "/getUserName", method = RequestMethod.GET)
	@ResponseBody
	public String getUserName(HttpServletRequest request) {

		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String strUserName = null;

		if (principal instanceof UserDetails) {
			strUserName = ((UserDetails) principal).getUsername();
		} else {
			strUserName = principal.toString();
		}

		return strUserName;
	}
	@RequestMapping(value = "/breadcrumb", method = RequestMethod.GET)
	public void getBreadCrumb() {
	}
	
	@RequestMapping(value = "/userRequestList")
	public @ResponseBody
	JQGridJSONModel displayServicesTable(HttpServletRequest request, @RequestParam(value = "page", required = true) String page,
			@RequestParam(value = "rows", required = true) String rows,
			@RequestParam(value = "sidx", required = true) String sidx,
			@RequestParam(value = "sord", required = true, defaultValue = "desc") String sord,
			@RequestParam(value = "_search", required = false) String isSearch,
			@RequestParam(value = "searchField", required = false) String searchField,
			@RequestParam(value = "searchOper", required = false) String searchOper,
			@RequestParam(value = "searchString", required = false) String searchString,
			Locale locale) {

		List<String> requestParameterNames = Collections.list((Enumeration<String>) request.getParameterNames());

		for (String parameterName : requestParameterNames) {
			System.out.println("parameterName = " + parameterName);

		}

		System.out.println("page==" + page);
		System.out.println("rows==" + rows);
		System.out.println("sidx==" + sidx);
		System.out.println("searchField==" + searchField);
		System.out.println("searchOper==" + searchOper);
		System.out.println("searchString==" + searchString);
		System.out.println("isSearch==" + isSearch);
		System.out.println("sord==" + sord);

		JQGridJSONModel result = new JQGridJSONModel();
		String userName = request.getRemoteUser();
		if(!org.apache.commons.lang.StringUtils.isBlank(userName)){
		    userName = WordUtils.capitalize(userName.toLowerCase(),new char[]{'.'});
		    
			// TEMPORARY FIX - Code added to make sure user name is matching with one in Active directory(case sensitive)
		    final String DOT_SEPERATOR = "."; 
		    final String MIDDLE_NAME = "Al";
		    if(StringUtils.startsWith(StringUtils.substringAfter(userName,DOT_SEPERATOR), MIDDLE_NAME))		    		
		    {
		    	String tempLastName = StringUtils.substringAfter(userName,DOT_SEPERATOR);	
		    	tempLastName = MIDDLE_NAME+WordUtils.capitalize(StringUtils.substringAfter(tempLastName,MIDDLE_NAME));
		    	userName = StringUtils.substringBefore(userName,DOT_SEPERATOR)+DOT_SEPERATOR+tempLastName;
		    }
		    // End TEMP FIX		    
		}


		//List<WorkflowRequestVO> requests = this.userDelegate.getUserWorkflowRequests(userName);
		List<UserRequestVO> requests = getUserRequestList(request);
		Integer pageIndx = 1, count = 0, totalpages = 0, start = 0;
		if(requests!= null){
		    count = requests.size();
		    
		    if("applicationDate".equalsIgnoreCase(sidx)){
		    Collections.sort(requests, new Comparator<UserRequestVO>() {
			    /**
			     * compare
			     * 
			     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
			     * 
			     */
			    public int compare(UserRequestVO o1,UserRequestVO o2) {
			    	return CommonUtils.getDateFromString(o1.getApplicationDate()).compareTo(CommonUtils.getDateFromString(o2.getApplicationDate()));
			    }
			});
		    }else{
		    		CommonUtils.sort(requests, sidx, true);	    	
		    }
		}
		Integer limit = 40;
		try {
			pageIndx = Integer.parseInt(page);
		} catch (Exception nullexp) {
			pageIndx = 1;
		}
		try {
			limit = Integer.parseInt(rows);
		} catch (Exception nullexp) {
			pageIndx = 10;
		}

		if (count > 0)
			totalpages = (int) Math.ceil(((float) count) / (float) limit);
		else
			totalpages = 0;

		if (pageIndx > totalpages)
			pageIndx = totalpages;

		start = (limit * pageIndx) - limit;
		result.setPage(pageIndx.toString());
		result.setRecords(count + "");
		result.setTotal(totalpages + "");
		
		PagingVO pagingVO = new PagingVO();
		pagingVO.setStart(start);
		pagingVO.setSearchfieldName(searchField);
		pagingVO.setSerachString(searchString);
		pagingVO.setSortFieldName(sidx);
		pagingVO.setSortOrder(sord);
		pagingVO.setPageNumber(pageIndx);
		pagingVO.setPageSize(limit);
		

		if(requests!=null){
			if(ConstantsAdmin.DESC_ORDER.equalsIgnoreCase(sord)){
				Collections.reverse(requests);
			}
        		//for (WorkflowRequestVO requestVO : requests) {
		    	for(int idx = start, elmts = 0; idx < requests.size() && elmts < limit; idx++, elmts++){
		    	    UserRequestVO requestVO = requests.get(idx);
		    	    if(requestVO != null){
        			List<String> cells = new ArrayList<String>();
        			cells.add(requestVO.getApplicationDate());
        			cells.add(requestVO.getStrClientRefNo());
        			cells.add(requestVO.getStrProcessCode());
        			cells.add(requestVO.getStrProcessCodeDescAr());
        			cells.add(requestVO.getStrProcessCodeDescEn());
        			cells.add(requestVO.getStrWfStatus());
        			cells.add(requestVO.getStrStatusDescAr());
        			cells.add(requestVO.getStrStatusDescEn());
        			
        			if(requestVO.getApplicationLink() == null) {
        				
        				try {
							cells.add(        						
									request.getContextPath() +
									ViewPath.USER_GENERAL_REQUEST_VIEW +"/show.htm?refNo=" +
									URLEncoder.encode(SecurityUtils.encryptQueryParam(requestVO.getStrClientRefNo()), "UTF-8"));
						} catch (UnsupportedEncodingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
        			
        			}
        			else
        				cells.add(requestVO.getApplicationLink());
        			
        			
        			result.addRows(requestVO.getStrClientRefNo(), cells);
		    	    }
		    	}
		}
		return result;
	}

	public List<UserRequestVO> getUserRequestList(HttpServletRequest request) {

		List<UserRequestVO> userRequestVOs;
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String strUserName = null;

		if (principal instanceof UserDetails) {
			strUserName = ((UserDetails) principal).getUsername();
		} else {
			strUserName = principal.toString();
		}

		if (strUserName != null) {

			UserVO userVO = this.userDelegate.findUserByUserName(strUserName);

			if (userVO != null && userVO.getlUserId() != null) {
				userRequestVOs = new ArrayList<UserRequestVO>();

				//List<AppMetaDataDetailVO> appMetaDataVOs = this.appMetaDataDelegate.loadAppMetaDataByUserId(userVO.getlUserId());
				List<AppMetaDataDetailVO> appMetaDataVOs = this.appMetaDataDelegate.loadAppMetaDataByUserName(userVO.getStrUsrName());
				UserRequestVO userRequestVO;
				
				if(appMetaDataVOs != null && appMetaDataVOs.size() > 0)
				{
					for (AppMetaDataVO appMetaDataVO : appMetaDataVOs) {
	
						userRequestVO = new UserRequestVO();
						getMapper().map(appMetaDataVO, userRequestVO);
						userRequestVOs.add(userRequestVO);
					}
					if (userRequestVOs.size() > 0) {
						return userRequestVOs;
					}
				}
			}
		}

		return null;
	}

	/**
	 * Custom handler for displaying the form, i.e.: GET requests for
	 * /client/register/
	 * 
	 * @see WEB-INF/jsp/client/register/form.jsp
	 */

	@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(@ModelAttribute(value = ConstantsAdmin.CLIENT_REGISTER_MODEL_KEY) ClientLogin command) {
	}

	@RequestMapping(value = "/show.htm", method = RequestMethod.GET)
	public void show(HttpServletRequest request) {		
	}

	/**
	 * Custom handler for displaying the form, i.e.:POST requests for
	 * /client/register/form.jsp
	 * 
	 * @see #form(ClientLogin)
	 * @see WEB-INF/jsp/client/register/password/form.jsp
	 */

	@RequestMapping(method = RequestMethod.POST, value = "/form.htm")
	public String form(HttpServletRequest request, SessionStatus status,
			@ModelAttribute(value = ConstantsAdmin.CLIENT_REGISTER_MODEL_KEY) @Valid ClientLogin clientLogin, BindingResult errors) {

		boolean isSubmit = WebUtils.hasSubmitParameter(request, ConstantsAdmin.SUBMIT_BUTTON);

		if (isSubmit) {
			if (errors.hasErrors()) {
				/*
				 * for (Object object : errors.getAllErrors()) { if(object
				 * instanceof FieldError) { FieldError fieldError = (FieldError)
				 * object;
				 * 
				 * }
				 * 
				 * if(object instanceof ObjectError) { ObjectError objectError =
				 * (ObjectError) object;
				 * 
				 * } }
				 */

				return ViewUtils.DEFAULT_VIEW;

			} else {
				// ClientCompanyVO clientCompanyVO =
				// userDelegate.userValidation(clientLogin.getStrUserName(),
				// clientLogin.getStrPassword());
				ClientCompanyVO clientCompanyVO = null;
				if (clientCompanyVO == null) {
					String[] messageArgs = new String[] { getMessageSource().getMessage("label.client.login", null,
							RequestContextUtils.getLocale(request)) };
					errors.reject("error.invalid.username.password", messageArgs, null);
					return ViewUtils.DEFAULT_VIEW;
				}
			}

		}
		return ViewUtils.getRedirect(ViewPath.USER_SERVICE, PageType.FORM);
	}

}
